package com.hjy.elasticsearch.service.impl;

import com.hjy.elasticsearch.entity.Entity;
import com.hjy.elasticsearch.entity.OrderEntity;
import com.hjy.elasticsearch.service.CityESService;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestResult;
import io.searchbox.core.*;
import io.searchbox.indices.DeleteIndex;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

@Service
public class CityESServiceImpl implements CityESService{

    private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class);

    @Autowired
    private JestClient jestClient;

    /**
     * 保存单个实体类
     * @param entity
     * @return
     */
    @Override
    public Index saveEntity(Entity entity) {
        Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build();
        try {
            JestResult jestResult = jestClient.execute(index);
            LOGGER.info("ES 插入完成");
            return  index;
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
            return null;
        }
    }


    /**
     * 批量保存内容到ES
     */
    @Override
    public void saveEntity(List<Entity> entityList) {
        Bulk.Builder bulk = new Bulk.Builder();
        for(Entity entity : entityList) {
            Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build();
            bulk.addAction(index);
        }
        try {
            jestClient.execute(bulk.build());
            LOGGER.info("ES 批量插入完成");
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        }
    }

    /**
     * 删除？？
     */
    public void deleteES(){
        Delete delete = new Delete.Builder("").index(Entity.INDEX_NAME).type(Entity.TYPE).build();
        try {
            JestResult result = jestClient.execute(delete);
        } catch (IOException e) {
            e.printStackTrace();
            LOGGER.error(e.getMessage());
        }

    }
    /**
     * 根据ID删除文档
     * @throws Exception
     */
    public void deleteIndexDocument() throws Exception {
        String id = "2";
        DocumentResult dr = jestClient.execute(new Delete.Builder(id).index(Entity.INDEX_NAME).type(Entity.TYPE).build());
        boolean result = dr.isSucceeded();
        System.out.println(result);
    }
    /**
     * 删除索引
     * @throws Exception
     */
    public void deleteIndex() throws Exception {
        JestResult jr = jestClient.execute(new DeleteIndex.Builder(Entity.INDEX_NAME).build());
        boolean result = jr.isSucceeded();
        System.out.println(result);
    }
    /**
     * 在ES中搜索内容
     * index:索引名，这里查询的是Entity，所以索引名，必须是Entity的属性名
     * searchContent：检索的字符串
     */
    @Override
    public List searchEntity(String index,String searchContent,String tableName){
        QueryBuilder queryBuilder = QueryBuilders.matchQuery(index, searchContent)
                .fuzziness(Fuzziness.AUTO) // 模糊查询
                .prefixLength(3)    // 前缀查询的长度
                .maxExpansions(10); // max expansion 选项，用来控制模糊查询

        List<OrderEntity> list = findMatchQueryBuilder(queryBuilder,tableName,"link_"+tableName, OrderEntity.class);
        return list;
    }



    /**
     * 使用QueryBuilder
     * termQuery("key", obj) 完全匹配
     * termsQuery("key", obj1, obj2..)   一次匹配多个值
     * matchQuery("key", Obj) 单个匹配, field不支持通配符, 前缀具高级特性
     * multiMatchQuery("text", "field1", "field2"..);  匹配多个字段, field有通配符忒行
     * matchAllQuery();         匹配所有文件
     */
    public Object search(String index,String searchContent,Object ... obj){
        QueryBuilder queryBuilders = QueryBuilders.multiMatchQuery("user", "kimchy");


        return null;
    }

    /**
     * 两列查询
     * @param index
     * @param index2
     * @param searchContent
     * @return
     */
    @Override
    public Object searchTwo(String index,String index2,String searchContent){
        QueryBuilder queryBuilders = QueryBuilders.multiMatchQuery(searchContent, index,index2);


        return findMatchQueryBuilder(queryBuilders);
    }

    /**
     * 多列查询
     * @param searchContent
     * @param index
     * @return
     */
    @Override
    public Object searchmore(int pageNumber,int pageSize,String searchContent,String ... index){
        QueryBuilder queryBuilders = QueryBuilders.multiMatchQuery(searchContent, index);
    //    return findMatchQueryBuilder(queryBuilders);
        return page(queryBuilders,pageNumber,pageSize);
    }

    /**
     * 排序 分页查询
     * @param queryBuilder
     * @param pageNumber:第几页，从一开始
     * @param pageSize：每页数量
     * @return
     */
    public Object page(QueryBuilder queryBuilder,int pageNumber,int pageSize){

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        searchSourceBuilder.from((pageNumber - 1) * pageSize);//设置起始页
        searchSourceBuilder.size(pageSize);//设置页大小
        searchSourceBuilder.sort("id", SortOrder.DESC);//排序

        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(Entity.INDEX_NAME).addType(Entity.TYPE).build();

        try {
            JestResult result = jestClient.execute(search);
            return result.getSourceAsObjectList(Entity.class);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 查询条件
     * @param queryBuilder
     * @return
     */
    private Object findMatchQueryBuilder(QueryBuilder queryBuilder){
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        LOGGER.info(".....1........: "+searchSourceBuilder.toString());

        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(Entity.INDEX_NAME)
                .addType(Entity.TYPE)
//                .addIndex("nonself_food_order_detail_info")
//                .addType("link_nonself_food_order_detail_info")
                .build();

        try {
            LOGGER.info(".......2......: "+search.toString());
            JestResult result = jestClient.execute(search);
            return result.getSourceAsObjectList(Entity.class);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 查询条件
     * @param queryBuilder
     * @return
     */
    private <T> List<T> findMatchQueryBuilder(QueryBuilder queryBuilder, String ESIndex,String ESType,Class<T> type ){
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        LOGGER.info(".....1........: "+searchSourceBuilder.toString());

        Search search = new Search.Builder(searchSourceBuilder.toString())
                .addIndex(ESIndex)
      //          .addType(ESType)
                .build();

        try {
            LOGGER.info(".......2......: "+search.toString());
            JestResult result = jestClient.execute(search);
            return result.getSourceAsObjectList(type);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }
}
























